﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Objects;

namespace NAccounting
{
    public partial class Lot
    {
        public bool CanSave { get { return true; } }
        public bool CanSaveAndOpenLote { get { return this.Id == 0; } }
        public bool CanCloseLote { get { return this.OpenDate.HasValue; } }
        public bool CanCreateAccountingEntry { get { return this.Id > 0; } }
        public bool IsClosed { get { return this.CloseDate.HasValue; } }
        public bool IsBalanced { get { return this.TotalCredit == this.TotalDebit; } }
        public bool MayReceiveRelease { get { return !CloseDate.HasValue; } }

        public void Open()
        {
            if (!this.OpenDate.HasValue)
            {
                this.OpenDate = DateTime.Now;
            }
        }

        public void Close()
        {
            if (TotalCredit != TotalDebit)
                throw new InvalidOperationException("Não é possível fechar o lote pois o total de crédito e débito encontra-se desbalanceado");

            if (!this.CloseDate.HasValue)
            {
                this.CloseDate = DateTime.Now;
            }
        }

        public void Balance() 
        {
            TotalCredit = AccountEntries.Where(x => x.Type == AccountEntryType.Credit.ToString()).Sum(x => x.Value);
            TotalDebit = AccountEntries.Where(x => x.Type == AccountEntryType.Debit.ToString()).Sum(x => x.Value);
        }

        public void Add(AccountEntry accountEntry)
        {
            AccountEntries.Add(accountEntry);
            Balance();
        }

        public void Remove(AccountEntry accountEntry)
        {
            AccountEntries.Remove(accountEntry);
            Balance();
        }
    }

    public static class LotCollectionExtensions
    {
        public static bool AnyUnbalanced(this IEnumerable<Lot> source)
        {
            return source.Any(x => x.TotalDebit != x.TotalCredit);
        }

        public static void CloseAll(this IEnumerable<Lot> source)
        {
            foreach (var lot in source)
            {
                lot.Close();
            }
        }
    }

}